package com.project.server.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.project.server.common.exception.BusinessException;
import com.project.server.dto.MedicalRecordDTO;
import com.project.server.entity.*;
import com.project.server.dto.ScheduleDTO;
import com.project.server.dto.MedicalAdviceDTO;
import com.project.server.mapper.*;
import com.project.server.service.DoctorService;
import com.project.server.vo.doctor.DoctorVO;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import lombok.extern.slf4j.Slf4j;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;

import java.math.BigDecimal;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.Period;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.time.format.DateTimeFormatter;

@Service
@Slf4j
public class DoctorServiceImpl implements DoctorService {


    @Autowired
    private DoctorAppointmentMapper appointmentMapper;

    @Autowired
    private HealthRecordMapper healthRecordMapper;

    @Autowired
    private SysUserMapper sysUserMapper;

    @Autowired
    private DoctorScheduleMapper scheduleMapper;


    @Autowired
    private PasswordEncoder passwordEncoder;



    @Override
    @Transactional
    public Boolean saveDoctor(DoctorVO doctorVO) {
        // 创建用户
        SysUser user = new SysUser();
        user.setUsername(doctorVO.getUsername());
        user.setPassword(passwordEncoder.encode(doctorVO.getPassword()));
        user.setRealName(doctorVO.getRealName());
        user.setRoleId(2); // 医生角色
        user.setSpecialty(doctorVO.getSpecialty()); // 医生角色
        int insert = sysUserMapper.insert(user);
        return insert > 0 ? true : false;
    }

    @Override
    @Transactional
    public Boolean updateDoctor(DoctorVO doctorVO) {
        SysUser sysUser = sysUserMapper.selectById(doctorVO.getId());
        if (sysUser != null) {

            sysUser.setSpecialty(doctorVO.getSpecialty());
            sysUser.setRealName(doctorVO.getRealName());
            sysUser.setUsername(doctorVO.getUsername());
            sysUser.setIsAuth(doctorVO.getIsAuth());
            int i = sysUserMapper.updateById(sysUser);
            return i > 0 ? true : false;
        }
        return false;
    }

    @Override
    @Transactional
    public Boolean removeById(Long id) {
        int i = sysUserMapper.deleteById(id);
        return i > 0 ? true : false;
    }

    @Override
    public List<HealthRecord> getPatientHealthRecords(Long patientId) {
        LambdaQueryWrapper<HealthRecord> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(HealthRecord::getUserId, patientId)
                .orderByDesc(HealthRecord::getCreateTime);

        return healthRecordMapper.selectList(wrapper);
    }

    @Override
    public Page<DoctorAppointment> getAppointmentList(Long doctorId, Integer status, Integer current, Integer size) {
        Page<DoctorAppointment> page = new Page<>(current, size);

        LambdaQueryWrapper<DoctorAppointment> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(DoctorAppointment::getDoctorId, doctorId)
                .eq(status != null, DoctorAppointment::getStatus, status)
                .orderByDesc(DoctorAppointment::getAppointmentTime);

        return appointmentMapper.selectPage(page, wrapper);
    }

    @Override
    @Transactional
    public void updateAppointmentRecord(Long appointmentId, String diagnosis, String prescription) {
        DoctorAppointment appointment = appointmentMapper.selectById(appointmentId);
        if (appointment == null) {
            throw new RuntimeException("预约不存在");
        }

        if (appointment.getStatus() != 2) { // 2表示已完成
            throw new RuntimeException("只能更新已完成的就诊记录");
        }

        appointment.setDiagnosis(diagnosis);
        appointment.setPrescription(prescription);
        appointmentMapper.updateById(appointment);
    }



    @Override
    public List<Map<String, Object>> getTodayAppointments(Long doctorId) {
        LocalDateTime today = LocalDate.now().atStartOfDay();
        LocalDateTime tomorrow = today.plusDays(1);

        List<DoctorAppointment> appointments = appointmentMapper.selectList(
            new LambdaQueryWrapper<DoctorAppointment>()
                .eq(DoctorAppointment::getDoctorId, doctorId)
                .between(DoctorAppointment::getAppointmentTime, today, tomorrow)
                .orderByAsc(DoctorAppointment::getAppointmentTime)
        );

        return appointments.stream().map(appointment -> {
            Map<String, Object> map = new HashMap<>();
            map.put("id", appointment.getId());
            map.put("patientName", appointment.getPatientName());
            map.put("appointmentTime", appointment.getAppointmentTime());
            map.put("status", appointment.getStatus());
            map.put("description", appointment.getSymptoms());
            return map;
        }).collect(Collectors.toList());
    }


    @Override
    public SysUser getDoctorInfo(Long doctorId) {
        SysUser sysUser = sysUserMapper.selectById(doctorId);
        if (sysUser == null) {
            throw new BusinessException("医生信息不存在");
        }
        return sysUser;
    }


    @Override
    public boolean updateAppointmentStatus(Long id, Integer status) {
        DoctorAppointment appointment = appointmentMapper.selectById(id);
        if (appointment == null) {
            throw new BusinessException("预约信息不存在");
        }

        appointment.setStatus(status);
        return appointmentMapper.updateById(appointment) > 0;
    }




}
